<?php

namespace paper\view;

use http\Exception\RuntimeException;
use paper\exception\HttpException;
use paper\helper\DotAccessTrait;
use paper\http\Request;

class View2
{
    private string $viewPath = "";
    public array $block = [];
    public array $var = [];
    private string|null $extend = null;
    protected Request $request;
    private $bockName;

    use DotAccessTrait;

    public function __construct()
    {
        $this->request = app()->request;
    }

    /**
     * @return string
     */
    public function getViewPath(): string
    {
        return $this->viewPath;
    }

    private function parsePath($path): string
    {
        return $this->viewPath . $path . '.php';
    }

    /**
     * @param string $viewPath
     */
    public function setViewPath(string $viewPath): void
    {
        $this->viewPath = $viewPath;
    }

    public function url(string $path): string
    {
        if (str_starts_with($path, "/")) {
            return $path;
        }

    }

    public function setLayout(string $extend): static
    {
        $absPath = $this->parsePath($extend);
        if (!is_file($absPath))
            throw new RuntimeException($absPath . "布局文件不存在");
        $this->extend = $this->parsePath($extend);
        return $this;
    }

    public function block($name, $value)
    {
        $this->block[$name] = $value;
    }

    /**
     * @param string $name
     * @return void
     */
    public function beginBlock(string $name)
    {
        $this->bockName = $name;
//        if (ob_get_length())
//            ob_clean();
        ob_start();
//        ob_start(function (string $buffer, int $phase) use ($name) {
//            $this->block($name, $buffer);
//            return '';
//        });
    }

    public function endBlock()
    {
        $this->block($this->bockName, ob_get_clean());
    }

    public function html($var): string
    {
        return htmlspecialchars($var, ENT_QUOTES);
    }

    public function o(string $field, ?string $default = ''): string
    {
        return $this->out($field, $default);
    }

    public function out(string $field, ?string $default = ''): string
    {
        return htmlspecialchars($this->dotAccess($field, $this->var, $default), ENT_QUOTES);
    }

    public function raw(string $field, ?string $default = ''): string
    {
        return $this->dotAccess($field, $this->var, $default);
    }

    public function assign($name, $value)
    {
        $this->var[$name] = $value;
    }

    public function renderBlock($name): bool
    {
        if (isset($this->block[$name])) {
            echo $this->block[$name];
            return true;
        }
        return false;
    }

    /**
     * @param string $view
     * @param array $vars
     * @return string
     * @throws HttpException
     */
    public function render(string $view, array $vars = []): string
    {
        $this->var = array_merge($this->var, $vars);
        $viewFilename = $this->parsePath($view);
        if (!is_file($viewFilename))
            throw new HttpException(404, $viewFilename . "模板文件不存在");
        ob_start();
        ob_implicit_flush(false);

        include($viewFilename);
        $content = ob_get_length() ? ob_get_clean() : '';
        if ($this->extend) //使用了模板继承功能
        {
            include($this->extend);
            $content = ob_get_length() ? ob_get_clean() : '';
        }

        return $content;
    }
}